package com.black.utils.random;

import lombok.extern.slf4j.Slf4j;

import java.awt.*;
import java.util.Random;
import java.util.UUID;

/**
 * @author ylx
 */
@Slf4j
public class RandomUtil {
    private static final Random RANDOM = new Random();

    public static String generateUUID() {
        return UUID.randomUUID().toString().replaceAll("-", "");
    }

    /**
     * Generates a random integer within the specified range.
     * 生成指定范围内的随机整数。
     *
     * @param min Minimum value (inclusive).
     *            最小值（包含）。
     * @param max Maximum value (inclusive).
     *            最大值（包含）。
     * @return Random integer within the specified range.
     * 指定范围内的随机整数。
     * @throws IllegalArgumentException if min is greater than max.
     *                                  如果最小值大于最大值。
     */
    public static int nextInt(int min, int max) {
        if (min > max) {
            log.error("Min must be less than or equal to max");
            throw new IllegalArgumentException("Min must be less than or equal to max");
        }
        return RANDOM.nextInt(max - min + 1) + min;
    }

    /**
     * Generates a random integer between 0 and max.
     * 生成0-最大值范围内的随机整数。
     *
     * @param max Maximum value (inclusive).
     *            最大值（包含）。
     * @return Random integer within the specified range.
     * 指定范围内的随机整数。
     */
    public static int nextInt(int max) {
        return nextInt(0, max);
    }

    /**
     * Generates a random double within the specified range.
     * 生成指定范围内的随机双精度浮点数。
     *
     * @param min Minimum value (inclusive).
     *            最小值（包含）。
     * @param max Maximum value (exclusive).
     *            最大值（不包含）。
     * @return Random double within the specified range.
     * 指定范围内的随机双精度浮点数。
     * @throws IllegalArgumentException if min is greater than or equal to max.
     *                                  如果最小值大于或等于最大值。
     */
    public static double nextDouble(double min, double max) {
        if (min >= max) {
            log.error("Min must be less than max");
            throw new IllegalArgumentException("Min must be less than max");
        }
        return min + (max - min) * RANDOM.nextDouble();
    }

    /**
     * Generates a random double between 0.0 (inclusive) and max (exclusive).
     * 生成介于0.0（包含）和最大值（不包含）之间的随机双精度浮点数。
     *
     * @param max Maximum value (exclusive).
     *            最大值（不包含）。
     * @return Random double within the specified range.
     * 指定范围内的随机双精度浮点数。
     */
    public static double nextDouble(double max) {
        return nextDouble(0.0, max);
    }

    /**
     * Generates a random double between 0.0 (inclusive) and 1.0 (exclusive).
     * 生成介于0.0（包含）和1.0（不包含）之间的随机双精度浮点数。
     *
     * @return Random double between 0.0 and 1.0.
     * 介于0.0和1.0之间的随机双精度浮点数。
     */
    public static double nextDouble() {
        return RANDOM.nextDouble();
    }

    /**
     * 随机生成一个float
     *
     * @return float
     */
    public static float nextFloat() {
        return RANDOM.nextFloat();
    }

    /**
     * 生成一个随机的布尔值。
     * <p>
     * 本方法通过调用RANDOM对象的nextBoolean方法来获取一个随机的布尔值（true或false）。
     * 这种随机性是由java.util.Random类的内部算法保证的，使得每次调用本方法时返回的值都是不确定的。
     *
     * @return 随机的布尔值，可能是true或false。
     */
    public static boolean nextBoolean() {
        return RANDOM.nextBoolean();
    }


    /**
     * 根据给定的起始色和结束色生成一个随机颜色。
     * <p>
     * 此方法用于生成一个介于给定的起始色（fc）和结束色（bc）之间的随机颜色。
     * 起始色和结束色的RGB值应该在0到255之间。如果提供的值超过这个范围，将会被截断到255。
     * 生成的颜色的RGB值将是起始色和结束色之间的一个随机值。
     *
     * @param fc 起始色的RGB值。如果超过255，将被截断到255。
     * @param bc 结束色的RGB值。如果超过255，将被截断到255。
     * @return 一个随机生成的颜色，其RGB值在起始色和结束色之间。
     */
    public static Color nextColor(int fc, int bc) {
        // 确保起始色和结束色的值不超过255
        if (fc > 255) {
            fc = 255;
        }
        if (bc > 255) {
            bc = 255;
        }

        // 生成随机的红、绿、蓝分量，确保它们在起始色和结束色之间
        int r = fc + RANDOM.nextInt(bc - fc);
        int g = fc + RANDOM.nextInt(bc - fc);
        int b = fc + RANDOM.nextInt(bc - fc);

        // 使用生成的红、绿、蓝分量创建并返回一个新的颜色对象
        return new Color(r, g, b);
    }


    /**
     * 生成一个随机整数颜色值。
     * <p>
     * 该方法通过生成一个包含RGB三个分量的随机数组，并将这三个分量组合成一个整数颜色值。
     * RGB分量分别是红色、绿色和蓝色，每种分量的值在0到255之间，这个范围内可以表示所有的颜色。
     * 组合颜色时，先将每个分量左移8位，然后通过按位或操作将它们组合在一起，形成一个32位整数颜色值。
     *
     * @return 随机整数颜色值，格式为0xRRGGBB。
     */
    public static int getRandomIntColor() {
        // 生成随机的RGB颜色分量
        int[] rgb = getRandomRgb();
        int color = 0;
        // 将RGB分量组合成一个整数颜色值
        for (int c : rgb) {
            color = color << 8; // 将已有的颜色值左移8位，为新的分量腾出空间
            color = color | c; // 将当前分量c通过按位或操作加入到颜色值中
        }
        return color; // 返回组合后的整数颜色值
    }


    /**
     * 生成一个包含随机RGB值的数组。
     * RGB值的范围是0到255，这个方法用于生成随机颜色，可以用于需要随机颜色的场景，比如图形渲染或随机标志生成。
     *
     * @return int[] - 包含三个整数的数组，分别代表红色、绿色和蓝色的随机值。
     */
    public static int[] getRandomRgb() {
        // 初始化一个长度为3的数组，用于存放RGB值。
        int[] rgb = new int[3];

        // 对RGB的每个分量分别生成随机数。
        for (int i = 0; i < 3; i++) {
            // 生成0到255之间的随机整数，用于RGB颜色值。
            rgb[i] = nextInt(255);
        }

        // 返回包含随机RGB值的数组。
        return rgb;
    }
}
